package org.jeecg.modules.nikeProject.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.desensitization.enums.SensitiveEnum;
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
import org.jeecg.common.util.DySmsEnum;
import org.jeecg.common.util.DySmsHelper;
import org.jeecg.common.util.EmailUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.sms.SmsUtil;
import org.jeecg.modules.nikeProject.entity.*;
import org.jeecg.modules.nikeProject.entity.vo.*;
import org.jeecg.modules.nikeProject.mapper.*;
import org.jeecg.modules.nikeProject.service.ISportsProjectService;
import org.jeecg.modules.oss.entity.OssFile;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description: 案例评审-项目管理
 * @Author: jeecg-boot
 * @Date: 2024-12-05
 * @Version: V1.0
 */
@Service
@Slf4j
public class SportsProjectServiceImpl extends ServiceImpl<SportsProjectMapper, SportsProject> implements ISportsProjectService {

    @Autowired
    private SportsPersonalInfoMapper personalInfoMapper;

    @Autowired
    private SportsPersonalEduMapper personalEduMapper;

    @Autowired
    private SportsPersonalWorkExperienceMapper personalWorkExperienceMapper;

    @Autowired
    private SportsCaseReportMapper caseReportMapper;

    @Autowired
    private SportsWorkInfoMapper workInfoMapper;

    @Autowired
    private SportsWorkInfoSchoolMapper sportsWorkInfoSchoolMapper;

    @Autowired
    private SportsWorkInfoCertifierMapper sportsWorkInfoCertifierMapper;

    @Autowired
    private SportsWorkInfoSupportMapper sportsWorkInfoSupportMapper;

    @Autowired
    private SportsProjectMapper projectMapper;

    @Autowired
    private SportsQualificationDocMapper qualificationDocMapper;

    @Autowired
    private SportsReferenceMapper sportsReferenceMapper;

    @Autowired
    private SportsObservationThinkingMapper sportsObservationThinkingMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysDictMapper sysDictMapper;

    @Autowired
    private SportsProjectFileMapper sportsProjectFileMapper;

    @Autowired
    private SportsProjectReviewMapper sportsProjectReviewMapper;

    @Autowired
    private SportsScoreRuleMapper sportsScoreRuleMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private SendEmailLogMapper sendEmailLogMapper;

    @Autowired
    private SportsProjectSupplymentaryMapper sportsProjectSupplymentaryMapper;

    @Autowired
    private SportsProjectCoefficientMapper sportsProjectCoefficientMapper;

    @Autowired
    private RedisUtil redisUtil;

    private final String replaceCaseName = "年活力校园参选案例";
    @Autowired
    private SportsProjectMapper sportsProjectMapper;

    private Integer getCurrentYear(){
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return year;
    }

    /**
     * 评委、nike团队查看项目详情接口
     *
     * @param projectId
     * @param roleType   8-填报人 5-评审 7-nike内部人员
     * @param step       1-个人基本信息，2-个人日常工作情况，3-案例申报，4-观察思考, 5-申报推荐人，6-上传资质文件  7-补充材料 8-国际行  11-查看评审打分信息
     * @param username   当前登陆用户
     * @param reviewId   普通/专家评审的评审表ID
     * @param reviewType 1-普通专家评审后 2-资深专家评审后 3-国际行评审后
     * @return
     */
    @Override
    public Result<ProjectInfoVO> getProjectDetail(String projectId, String roleType, String step, String username, String reviewId, String reviewType) {
        ProjectInfoVO projectInfoVO = new ProjectInfoVO();
        //获取当前登陆用户的id
        String userId = sysUserMapper.getUserByName(username).getId();
        SportsProject sportsProject = projectMapper.selectById(projectId);
        if (null != sportsProject) {
            SportsCaseReport sportsCaseReport = getCaseReportByProjectId(projectId);
            String caseName = sportsProject.getProjectName();
            String caseType = sportsProject.getCaseType();
            if (null != caseType && !"".equals(caseType)) {
                projectInfoVO.setCaseType(caseType);
                projectInfoVO.setCaseTypeName(getCaseTypeNameByCaseType(caseType));
            }
            if (null != sportsCaseReport) {
                String otherCase = sportsCaseReport.getOtherCase();
                projectInfoVO.setOtherCaseName(getOtherCaseName(caseType, otherCase));
                projectInfoVO.setOtherCase(otherCase);
                //当申报案例书中无法取到学段信息时，取用户信息填报中的数据
                String courseStage = getCourseStage(sportsCaseReport.getCourseStage(), projectId);
                projectInfoVO.setCourseStage(courseStage);
            }
            projectInfoVO.setRoleType(sportsProject.getRoleType());

            //判断角色为评委
            if (CommonConstant.ROLE_TYPE_JUDGE_ORDINARY.equals(roleType) || CommonConstant.ROLE_TYPE_JUDGE_SENIOR.equals(roleType)) {
                //获取用户表中用户名，学校/工作单位
                SportsPersonalInfo sportsPersonalInfo = personalInfoMapper.selectByProjectId(projectId);
                String name = SensitiveInfoUtil.getDecodeData(sportsPersonalInfo.getName());
                String schoolName = sportsPersonalInfo.getSchoolName();
                String phone = SensitiveInfoUtil.getDecodeData(sportsPersonalInfo.getPhone());
                //案例名称字段做脱敏处理
                caseName = getDSTData(caseName, name,schoolName, phone, "spec");

                if (caseName.contains("年推广大使申报书")) {
                    projectInfoVO.setCaseName(caseName + "(" + projectId + ")");
                } else {
                    projectInfoVO.setCaseName(caseName);
                }

                if (CommonConstant.PROJECT_STEP_WORK_INFO.equals(step)) {
                    GetSportsWorkInfoRespVO workInfoRespVO = new GetSportsWorkInfoRespVO();

                    //查询案例-学校工作信息
                    SportsWorkInfo sportsWorkInfo = getWorkInfoByProjectId(projectId);
                    String sportStory = sportsWorkInfo.getSportStory();
                    if (sportStory != null && !"".equals(sportStory)) {
                        //关于体育的故事字段做脱敏处理
                        sportStory = getDSTData(sportStory, name,schoolName, phone, "");
                        log.info("脱敏后的体育故事数据为==={}", sportStory);
                        sportsWorkInfo.setSportStory(sportStory);
                    }
                    //获取推广大使工作内容
                    //校内
                    List<WorkInfoSchoolVO> inSchoolList = getSchoolData(projectId, CommonConstant.PROMOTION_TYPE_IN_SCHOOL);
                    workInfoRespVO.setInSchoolList(inSchoolList);
                    //校外
                    List<WorkInfoSchoolVO> outSchools = getSchoolData(projectId, CommonConstant.PROMOTION_TYPE_OUT_SCHOOL);
                    workInfoRespVO.setOutSchoolList(outSchools);
                    //如何推广
                    List<WorkInfoSupportVO> supportList = getSupportList(projectId);
                    workInfoRespVO.setSupportList(supportList);
                    workInfoRespVO.setSportsWorkInfo(sportsWorkInfo);
                    projectInfoVO.setWorkInfoRespVO(workInfoRespVO);
                }

                if (CommonConstant.PROJECT_STEP_CASE_REPORT.equals(step)) {
                    //案例申报书-案例正文
                    SportsCaseReportVO newSportsCaseReportVO = new SportsCaseReportVO();
                    if (null != sportsCaseReport) {
                        String caseContent = sportsCaseReport.getCaseContent();
                        if (caseContent != null && !"".equals(caseContent)) {
                            //案例正文字段做脱敏处理
                            caseContent = getDSTData(caseContent, name, schoolName, phone, "");
                            sportsCaseReport.setCaseContent(caseContent);
                        }
                    }
                    //获取案例视频文件
                    List<OssFileVO> videoList = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_VIDEO);
                    newSportsCaseReportVO.setVideoOssIds(videoList);
                    //文件图片
                    List<OssFileVO> fileOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_FILE);
                    newSportsCaseReportVO.setFileOssIds(fileOssIds);
                    newSportsCaseReportVO.setSportsCaseReport(sportsCaseReport);
                    projectInfoVO.setSportsCaseReportVO(newSportsCaseReportVO);
                }

                //查看补充材料
                if (CommonConstant.PROJECT_STEP_SUPPLEMENTARY.equals(step)) {
                    SupplementaryRespVO supplementaryRespVO = getSupplementaryData(projectId);
                    projectInfoVO.setSupplementaryRespVO(supplementaryRespVO);
                }

                //查看评审打分信息
                if (CommonConstant.PROJECT_STEP_SCORE.equals(step)) {
                    SportsProjectReview sportsProjectReview = null;
                    if (CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL.equals(reviewType)){
                        sportsProjectReview  = getReviewDetailById(userId, null, projectId, CommonConstant.REVIEW_TYPE_SENIOR);
                    } else {
                        sportsProjectReview = getReviewDetailById(userId, reviewId, projectId, null);
                    }
                    if (null != sportsProjectReview) {
                        List<ReviewScoreVO> reviewScoreVOS = new ArrayList<>();
                        ReviewScoreVO reviewScoreVO = getReviewScoreVO(sportsProjectReview);
                        reviewScoreVOS.add(reviewScoreVO);
                        projectInfoVO.setReviewList(reviewScoreVOS);
                    }
                }

                //查询观察与思考数据
                if (CommonConstant.PROJECT_STEP_OBSERVING_AND_THINKING.equals(step)) {
                    SportsObservationThinking sportsObservationThinking = getObservationThinking(projectId);
                    projectInfoVO.setSportsObservationThinking(sportsObservationThinking);
                }

                //查看评审国际行打分信息
                if (CommonConstant.PROJECT_STEP_INTERNATION_TRAVEL.equals(step)) {
                    SportsProjectReview internationalTravelReview = getReviewDetailById(userId, null, projectId, CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
                    if (null != internationalTravelReview) {
                        List<ReviewScoreVO> internationalTravelReveiwList = new ArrayList<>();
                        ReviewScoreVO reviewScoreVO = getReviewScoreVO(internationalTravelReview);
                        internationalTravelReveiwList.add(reviewScoreVO);
                        projectInfoVO.setInternationalTravelList(internationalTravelReveiwList);
                    }
                }
            } else { //角色为nike内部人员，或是填报人可查看
                projectInfoVO = getProjectByStep(projectId, step, projectInfoVO, reviewType, roleType);
                projectInfoVO.setCaseName(caseName);
                if (null != sportsCaseReport) {
                    boolean flag = checkCaseReportNull(sportsCaseReport, roleType);
                    if (!flag){
                        projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_0);
                    } else {
                        projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_1);
                    }
                } else {
                    projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_0);
                }
                projectInfoVO.setPersonInfoStatus(null != getSportsPersonalInfoByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
                projectInfoVO.setObservationStatus(null != getObservationThinking(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
                projectInfoVO.setWorkInfoStatus(null != getWorkInfoByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
                projectInfoVO.setQualificationStatus(null != getQualificationDocByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
                projectInfoVO.setReferenceStatus(null != getSportsReferences(projectId) && getSportsReferences(projectId).size() > 0 ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
                return Result.OK(projectInfoVO);
            }
        }
        return Result.OK("案例信息查询成功！", projectInfoVO);
    }

    public String getCourseStage(String courseStage, String projectId) {
        if (null == courseStage){
            SportsPersonalInfo sportsPersonalInfo = getSportsPersonalInfoByProjectId(projectId);
            courseStage = sportsPersonalInfo.getSchoolStage();
        }
        return courseStage;
    }

    @Override
    public String getDSTData(String field, String name, String schoolName, String phone, String type) {
        String replaceStr = field;
        if (field.contains(name)) {
            replaceStr = field.replaceAll(name, CommonConstant.ASTERISK);
        }
        if (field.contains(schoolName)) {
            replaceStr = field.replaceAll(schoolName, CommonConstant.ASTERISK);
        }
        if (type.equals("spec")) {
            if (field.contains(phone)) {
                replaceStr = field.replaceAll(phone, getCurrentYear() + replaceCaseName);
            }
        } else {
            replaceStr = field.replaceAll(phone, CommonConstant.ASTERISK);
        }
        return replaceStr;
    }

    public SupplementaryRespVO getSupplementaryData(String projectId){
        LambdaQueryWrapper<SportsProjectSupplementary> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProjectSupplementary::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsProjectSupplementary::getIzSubmit, CommonConstant.PROJECT_FIRST_AUDIT_STATUS_FINISH);
        lambdaQueryWrapper.eq(SportsProjectSupplementary::getIzActive, CommonConstant.COMMON_STATUS_N);
        SportsProjectSupplementary sportsProjectSupplementary = sportsProjectSupplymentaryMapper.selectOne(lambdaQueryWrapper);
        SupplementaryRespVO supplementaryRespVO = new SupplementaryRespVO();
        if (null != sportsProjectSupplementary) {
            BeanUtils.copyProperties(sportsProjectSupplementary, supplementaryRespVO);
            //第一部分图片/文件地址
            List<OssFileVO> fileVOS = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_SUPPLEMENTARY);
            if (null != fileVOS && fileVOS.size() > 0) {
                supplementaryRespVO.setSupplementaryFileVOS(fileVOS);
            }
            //第一部分视频地址
            List<OssFileVO> videoUrls = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_VIDEO);
            List<OssFileVO> newVideoUrls = new ArrayList<>();
            if (null != videoUrls && videoUrls.size() > 0) {
                videoUrls.forEach(x -> {
                    OssFileVO ossFileVO = sportsProjectFileMapper.getSourceType(sportsProjectSupplementary.getProjectId(), x.getOssFileId());
                    if (null != ossFileVO.getSourceType() && (ossFileVO.getSourceType().equals(CommonConstant.FILE_SOURCE_TYPE_FIRST)
                            || ossFileVO.getSourceType().equals(CommonConstant.FILE_SOURCE_TYPE_SECOND)
                            || ossFileVO.getSourceType().equals(CommonConstant.FILE_SOURCE_TYPE_THIRD))) {
                        OssFileVO newOssFileVO = new OssFileVO();
                        BeanUtils.copyProperties(x, newOssFileVO);
                        newOssFileVO.setSourceType(ossFileVO.getSourceType());
                        newOssFileVO.setIzCheck(ossFileVO.getIzCheck());
                        newVideoUrls.add(newOssFileVO);
                    }
                });
                supplementaryRespVO.setDescVideoUrls(newVideoUrls);
            }
        }
        return supplementaryRespVO;
    }

    public ReviewScoreVO getReviewScoreVO(SportsProjectReview sportsProjectReview) {
        ReviewScoreVO reviewScoreVO = new ReviewScoreVO();
        BeanUtils.copyProperties(sportsProjectReview, reviewScoreVO);
        reviewScoreVO.setJudgeUserName(getUserName(sportsProjectReview.getJudgeUserId()));
        List<RuleDetailVO> list = parseScoreDetail(sportsProjectReview.getScoreDetail());
        reviewScoreVO.setInternationTravelSummary(sportsProjectReview.getInternationalTravelSummary());
        reviewScoreVO.setList(list);
        return reviewScoreVO;
    }

    public String getUserName(String userId) {
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getId, userId);
        return sysUserMapper.selectOne(lambdaQueryWrapper).getRealname();
    }

    public List<RuleDetailVO> parseScoreDetail(String scoreDetail) {
        List<RuleDetailVO> list = new ArrayList<>();
        List<RuleVO> ruleVOS = JSONArray.parseArray(scoreDetail, RuleVO.class);
        if (null != ruleVOS && ruleVOS.size() > 0) {
            ruleVOS.forEach(x -> {
                RuleDetailVO ruleDetailVO = new RuleDetailVO();
                ruleDetailVO.setRuleId(x.getRuleId());
                ruleDetailVO.setScore(x.getScore());
                SportsScoreRule sportsScoreRule = getSportsScoreRuleById(x.getRuleId());
                ruleDetailVO.setRuleName(sportsScoreRule.getScoreContent());
                ruleDetailVO.setRuleNameDesc(sportsScoreRule.getScoreContentDesc());
                list.add(ruleDetailVO);
            });
        }
        return list;
    }

    public SportsScoreRule getSportsScoreRuleById(String ruleId) {
        LambdaQueryWrapper<SportsScoreRule> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsScoreRule::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsScoreRule::getId, ruleId);
        return sportsScoreRuleMapper.selectOne(lambdaQueryWrapper);
    }

    public SportsProjectReview getReviewDetailById(String userId, String reviewId, String projectId, String reviewType) {
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProjectReview::getJudgeUserId, userId);
        lambdaQueryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        if (null != reviewId && !"".equals(reviewId)) {
            lambdaQueryWrapper.eq(SportsProjectReview::getId, reviewId);
        }
        if (null != reviewType && !"".equals(reviewType)) {
            lambdaQueryWrapper.eq(SportsProjectReview::getReviewType, reviewType);
        }
        return sportsProjectReviewMapper.selectOne(lambdaQueryWrapper);
    }

    public String getCaseTypeNameByCaseType(String caseType) {
        String caseTypeName;
        switch (caseType) {
            case (CommonConstant.CASE_TYPE_TEACH):
                caseTypeName = CommonConstant.CASE_TYPE_TEACH_NAME;
                break;
            case (CommonConstant.CASE_TYPE_CULTURE):
                caseTypeName = CommonConstant.CASE_TYPE_CULTURE_NAME;
                break;
            case (CommonConstant.CASE_TYPE_ACTIVITY):
                caseTypeName = CommonConstant.CASE_TYPE_ACTIVITY_NAME;
                break;
            case (CommonConstant.CASE_TYPE_OTHER):
                caseTypeName = CommonConstant.CASE_TYPE_OTHER_NAME;
                break;
            default:
                caseTypeName = "";
        }
        return caseTypeName;
    }

    public String getOtherCaseName(String caseType, String otherCase) {
        String type = "";
        if (CommonConstant.CASE_TYPE_TEACH.equals(caseType)) {
            type = CommonConstant.CASE_TYPE_TEACH_EN;
        }
        if (CommonConstant.CASE_TYPE_CULTURE.equals(caseType)) {
            type = CommonConstant.CASE_TYPE_CULTURE_EN;
        }
        if (CommonConstant.CASE_TYPE_ACTIVITY.equals(caseType)) {
            type = CommonConstant.CASE_TYPE_ACTIVITY_EN;
        }
        if (CommonConstant.CASE_TYPE_OTHER.equals(caseType)) {
            type = CommonConstant.CASE_TYPE_OTHER_EN;
        }
        return sysDictMapper.getDictItemName(type, otherCase);
    }

    /**
     * @param projectId
     * @param step      1-个人基本信息，2-个人日常工作情况，3-案例申报，4-观察思考, 5-申报推荐人，6-上传资质文件，10-完成
     * @param username
     * @param roleType  1-一线体育老师  2-推广大使  3-校长 4-体育教研员 5-评审 7-nike内部人员
     * @return
     */
    @Override
    public Result<ProjectInfoVO> queryInfoByCode(String projectId, String step, String username, String roleType) {
        SysUser sysUser = sysUserMapper.getUserByName(username);
        SportsProject sportsProject = this.getSportsProject(projectId, sysUser.getId(), roleType);
        if (null != sportsProject) {
            projectId = sportsProject.getId();
            //判断当前用户是否能查看此案例
            if (!sportsProject.getUserId().equals(sysUser.getId())) {
                return Result.error("当前用户没有查看该案例的权限");
            }
            ProjectInfoVO projectInfoVO = new ProjectInfoVO();
            projectInfoVO.setProjectId(projectId);
            projectInfoVO.setRoleType(sportsProject.getRoleType());
            projectInfoVO.setProjectStep(sportsProject.getProjectStep());
            projectInfoVO.setProjectStatus(sportsProject.getProjectStatus());
            //查看案例每个步骤的完成情况
            projectInfoVO = this.getProjectByStep(projectId, step, projectInfoVO, null, null);
            projectInfoVO.setPersonInfoStatus(null != getSportsPersonalInfoByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
            projectInfoVO.setObservationStatus(null != getObservationThinking(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
            SportsCaseReport caseReport = getCaseReportByProjectId(projectId);
            if (null != caseReport) {
                boolean flag = checkCaseReportNull(caseReport, roleType);
                if (!flag){
                    projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_0);
                } else {
                    projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_1);
                }
            } else {
                projectInfoVO.setCaseReportStatus(CommonConstant.DEL_FLAG_0);
            }
//            projectInfoVO.setCaseReportStatus(null != getCaseReportByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
            projectInfoVO.setWorkInfoStatus(null != getWorkInfoByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
            projectInfoVO.setQualificationStatus(null != getQualificationDocByProjectId(projectId) ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);
            projectInfoVO.setReferenceStatus(null != getSportsReferences(projectId) && getSportsReferences(projectId).size() > 0 ? CommonConstant.DEL_FLAG_1 : CommonConstant.DEL_FLAG_0);

            return Result.OK("案例信息查询成功！", projectInfoVO);
        } else {
            return Result.error("此案例不存在");
        }
    }

    public SportsCaseReportVO getProjectCaseReportVO(String projectId) {
        SportsCaseReportVO sportsCaseReportVO = new SportsCaseReportVO();
        sportsCaseReportVO.setProjectId(projectId);
        SportsCaseReport caseReport = getCaseReportByProjectId(projectId);
        sportsCaseReportVO.setSportsCaseReport(caseReport);
        //查询案例申报中的视频和图片信息
        List<OssFileVO> videoOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_VIDEO);
        sportsCaseReportVO.setVideoOssIds(videoOssIds);
        List<OssFileVO> fileOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_FILE);
        sportsCaseReportVO.setFileOssIds(fileOssIds);
        return sportsCaseReportVO;
    }

    /**
     * @param projectId
     * @param step          1-个人基本信息，2-个人日常工作情况，3-案例申报，4-观察思考, 5-申报推荐人，6-上传资质文件， 11-查询评审打分情况
     * @param projectInfoVO
     * @param reviewType
     * @param roleType
     * @return
     */
    public ProjectInfoVO getProjectByStep(String projectId, String step, ProjectInfoVO projectInfoVO, String reviewType, String roleType) {
        switch (step) {
            case CommonConstant.PROJECT_STEP_PERSONAL_INFO:
                //查询案例-个人信息
                PersonalInfoVO personalInfoVO = getPersonalInfo(projectId, roleType);
                projectInfoVO.setPersonalInfoVO(personalInfoVO);
                break;
            case CommonConstant.PROJECT_STEP_WORK_INFO:
                //查询案例-学校工作信息
                SportsWorkInfo workInfo = getWorkInfoByProjectId(projectId);
                GetSportsWorkInfoRespVO workInfoRespVO = new GetSportsWorkInfoRespVO();
                //获取推广大使工作内容
                //校内
                List<WorkInfoSchoolVO> inSchoolList = getSchoolData(projectId, CommonConstant.PROMOTION_TYPE_IN_SCHOOL);
                workInfoRespVO.setInSchoolList(inSchoolList);
                //校外
                List<WorkInfoSchoolVO> outSchools = getSchoolData(projectId, CommonConstant.PROMOTION_TYPE_OUT_SCHOOL);
                workInfoRespVO.setOutSchoolList(outSchools);
                //如何推广
                List<WorkInfoSupportVO> supportList = getSupportList(projectId);
                workInfoRespVO.setSupportList(supportList);
                workInfoRespVO.setSportsWorkInfo(workInfo);
                projectInfoVO.setWorkInfoRespVO(workInfoRespVO);
                break;
            case CommonConstant.PROJECT_STEP_CASE_REPORT:
                //查询案例-案例申报书信息
                SportsCaseReportVO sportsCaseReportVO = getProjectCaseReportVO(projectId);
                projectInfoVO.setSportsCaseReportVO(sportsCaseReportVO);
                break;
            case CommonConstant.PROJECT_STEP_OBSERVING_AND_THINKING:
                //查询观察与思考数据
                SportsObservationThinking sportsObservationThinking = getObservationThinking(projectId);
                projectInfoVO.setSportsObservationThinking(sportsObservationThinking);
                break;
            case CommonConstant.PROJECT_STEP_APPLICATION_RECOMMENDER:
                //查询推荐人数据
                List<SportsReference> sportsReferences = getSportsReferences(projectId);
                projectInfoVO.setSportsReferences(sportsReferences);
                break;
            case CommonConstant.PROJECT_STEP_UPLOAD_QUALIFICATION_DOC:
                //资质文件
                SportsQualificationDoc qualificationDoc = getQualificationDocByProjectId(projectId);
                projectInfoVO.setQualificationDoc(qualificationDoc);
                break;
            case CommonConstant.PROJECT_STEP_SUPPLEMENTARY:
                //补充资料
                SupplementaryRespVO supplementaryRespVO = getSupplementaryData(projectId);
                projectInfoVO.setSupplementaryRespVO(supplementaryRespVO);
                break;
            case CommonConstant.PROJECT_STEP_INTERNATION_TRAVEL:
                //国际行
                List<ReviewScoreVO> internationalTravelList = getProjectReviewList(projectId, reviewType);
                projectInfoVO.setInternationalTravelList(internationalTravelList);
                break;
            default:
                //查询案例评分列表
                List<ReviewScoreVO> reviewList = getProjectReviewList(projectId, reviewType);
                projectInfoVO.setReviewList(reviewList);
        }
        return projectInfoVO;
    }

    public List<WorkInfoSupportVO> getSupportList(String projectId) {
        List<WorkInfoSupportVO> supportVOS = new ArrayList<>();
        LambdaQueryWrapper<SportsWorkInfoSupport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsWorkInfoSupport::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsWorkInfoSupport::getProjectId, projectId);
        List<SportsWorkInfoSupport> list = sportsWorkInfoSupportMapper.selectList(lambdaQueryWrapper);
        if (null != list && list.size() > 0) {
            list.forEach(x -> {
                WorkInfoSupportVO supportVO = new WorkInfoSupportVO();
                supportVO.setSupportStyle(x.getSupportStyle());
                supportVO.setDescription(x.getDescription());
                supportVOS.add(supportVO);
            });
        }
        return supportVOS;
    }

    public List<WorkInfoSchoolVO> getSchoolData(String projectId, String promotionType) {
        List<WorkInfoSchoolVO> schoolVOS = new ArrayList<>();
        List<SportsWorkInfoSchool> schools = getSchoolList(projectId, promotionType);
        if (null != schools && schools.size() > 0) {
            for (SportsWorkInfoSchool workInfoSchool : schools) {
                WorkInfoSchoolVO workInfoSchoolVO = new WorkInfoSchoolVO();
                List<SportsWorkInfoCertifier> list = getWorkInfoCertifier(projectId, workInfoSchool.getId(), promotionType);
                workInfoSchoolVO.setActivityMsg(workInfoSchool.getActivityMsg());
                workInfoSchoolVO.setActivityNum(workInfoSchool.getActivityNum());
                workInfoSchoolVO.setActivityName(workInfoSchool.getActivityName());
                workInfoSchoolVO.setPromotionType(promotionType);
                workInfoSchoolVO.setScopeAndCover(workInfoSchool.getScopeAndCover());
                workInfoSchoolVO.setCertifiers(list);
                //文件，图片，视频
                List<OssFileVO> ossFileVOS = sportsProjectFileMapper.getSchoolOssFiles(projectId, workInfoSchool.getId(), promotionType);
                workInfoSchoolVO.setOssFileVOS(ossFileVOS);
                schoolVOS.add(workInfoSchoolVO);
            }
        }
        return schoolVOS;
    }


    public List<SportsWorkInfoCertifier> getWorkInfoCertifier(String projectId, String workInfoSchool, String promotionType) {
        LambdaQueryWrapper<SportsWorkInfoCertifier> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsWorkInfoCertifier::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsWorkInfoCertifier::getWorkInfoSchoolId, workInfoSchool);
        lambdaQueryWrapper.eq(SportsWorkInfoCertifier::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsWorkInfoCertifier::getPromotionType, promotionType);
        return sportsWorkInfoCertifierMapper.selectList(lambdaQueryWrapper);
    }

    public List<SportsWorkInfoSchool> getSchoolList(String projectId, String promotionType) {
        LambdaQueryWrapper<SportsWorkInfoSchool> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsWorkInfoSchool::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsWorkInfoSchool::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsWorkInfoSchool::getPromotionType, promotionType);
        return sportsWorkInfoSchoolMapper.selectList(lambdaQueryWrapper);
    }

    public List<ReviewScoreVO> getProjectReviewList(String projectId, String reviewType) {
        List<ReviewScoreVO> list = new ArrayList<>();
        List<SportsProjectReview> reviews = getSportsReviewListByProjectId(projectId, reviewType);
        if (null != reviews && reviews.size() > 0) {
            for (int i = 0; i < reviews.size(); i++) {
                SportsProjectReview sportsProjectReview = reviews.get(i);
                ReviewScoreVO reviewScoreVO = getReviewScoreVO(sportsProjectReview);
                list.add(reviewScoreVO);
            }
        }
        return list;
    }

    public List<SportsProjectReview> getSportsReviewListByProjectId(String projectId, String reviewType) {
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, "0");
        lambdaQueryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        if (!"".equals(reviewType) && null != reviewType) {
            List<String> types = new ArrayList<>();
            if (CommonConstant.REVIEW_TYPE_ORDINARY.equals(reviewType)) {
                types.add("1");
                types.add("3");
            }
            if (CommonConstant.REVIEW_TYPE_SENIOR.equals(reviewType)) {
                types.add("2");
                types.add("4");
            }
            if (CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL.equals(reviewType)) {
                types.add("5");
            }
            lambdaQueryWrapper.in(SportsProjectReview::getReviewType, types);
        }
        return sportsProjectReviewMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 通过项目ID，角色类型查询当前用户对应的案例信息
     *
     * @param userId
     * @param roleType 1-一线体育老师  2-推广大使  3-校长 4-体育教研员 5-评审 7-nike内部人员
     * @return
     */
    public SportsProject getSportsProject(String projectId, String userId, String roleType) {
        Calendar calendar = Calendar.getInstance();
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getUserId, userId);
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        if (null != projectId && !"".equals(projectId)) {
            lambdaQueryWrapper.eq(SportsProject::getId, projectId);
        } else {
            lambdaQueryWrapper.eq(SportsProject::getYear, calendar.get(Calendar.YEAR));
            lambdaQueryWrapper.eq(SportsProject::getRoleType, roleType);
        }
        return projectMapper.selectOne(lambdaQueryWrapper);
    }

    /**
     * 查询案例对应的观察与思考
     *
     * @param projectId
     * @return
     */
    public SportsObservationThinking getObservationThinking(String projectId) {
        LambdaQueryWrapper<SportsObservationThinking> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsObservationThinking::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsObservationThinking::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsObservationThinkingMapper.selectOne(lambdaQueryWrapper);
    }

    public int getJudgeNumByRoleType(String roleType) {
        String redisKey = "JUDGE_NUM:" + roleType;
        Integer num = (Integer) redisUtil.get(redisKey);
        if (null == num) {
            if (CommonConstant.ROLE_TYPE_SR.equals(roleType)){
                num = Integer.parseInt(sysDictMapper.getDictItemName(CommonConstant.JUDGE_NUM, "special"));
            } else {
                num = Integer.parseInt(sysDictMapper.getDictItemName(CommonConstant.JUDGE_NUM, "normal"));
            }
            redisUtil.set("JUDGE:NUM:" + roleType, num);
        }
        return num;
    }

    /**
     * 根据专家类型，从字典表中查询出每个案例需要分配多少位专家
     *
     * @param judgeType
     * @return
     */
    @Override
    public int getJudgeNum(String judgeType) {
        String itemValue;
        if (CommonConstant.REVIEW_TYPE_ORDINARY.equals(judgeType)) {
            itemValue = sysDictMapper.getDictItemName(CommonConstant.ORDINARY_DICT_CODE, "");
        } else {
            itemValue = sysDictMapper.getDictItemName(CommonConstant.SENIOR_DICT_CODE, "");
        }
        return Integer.parseInt(itemValue);
    }

    @Override
    public void averageScore(String judgeType, Integer year) {
        if (null == year) {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
        }
        //待评综合分
        String projectStatus = CommonConstant.REVIEW_TYPE_ORDINARY.equals(judgeType) ? CommonConstant.PROJECT_STATUS_AUDITING_ORDINARY : CommonConstant.PROJECT_STATUS_AUDITING_SENIOR;
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getProjectStatus, projectStatus);
        lambdaQueryWrapper.eq(SportsProject::getYear, year);
        List<SportsProject> list = projectMapper.selectList(lambdaQueryWrapper);

        //评完综合分
        String finishStatus = CommonConstant.REVIEW_TYPE_ORDINARY.equals(judgeType) ? CommonConstant.PROJECT_STATUS_FINISH_ORDINARY : CommonConstant.PROJECT_STATUS_FINISH_SENIOR;
        //查询评审的数量
        if (null != list && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                SportsProject sportsProject = list.get(i);
                int num = getJudgeNumByRoleType(sportsProject.getRoleType());
//                log.info("更新当前案例评审打分，{}", sportsProject.getId());
                List<SportsProjectReview> reviews = sportsProjectReviewMapper.getSportsReviewStatus(
                        sportsProject.getId(), judgeType, CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
                //如果评审状态都为已提交
                if (null != reviews && reviews.size() > 0 && reviews.size() == num) {
                    log.info("当前案例:{},状态都为已提交", sportsProject.getId());
                    //判断是否有争议
                    int [] levelTypes = new int[num];
                    for (int j = 0; j < num; j++) {
                        levelTypes[j] = reviews.get(j).getLevelType();
                    }
//                    int [] levelTypes = new int[reviews.get(0).getLevelType(), reviews.get(1).getLevelType(),reviews.get(2).getLevelType()]
//                    boolean flag = checkDifference(reviews.get(0).getLevelType(), reviews.get(1).getLevelType(),reviews.get(2).getLevelType());
                    //判断是否存在等级大于等于3的，返回false表示存在，则设置为争议案例，返回true表示不存在，则直接通过
                    boolean flag = checkAllRatingDifferences(levelTypes);
                    if (!flag) {
                        sportsProject.setIzDispute(CommonConstant.COMMON_STATUS_Y);
                    } else {
                        sportsProject.setIzDispute(CommonConstant.COMMON_STATUS_N);
                    }
                    //求出平均分
                    BigDecimal sum = reviews.stream().map(SportsProjectReview::getScore).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal average = sum.divide(BigDecimal.valueOf(reviews.size()), 2, BigDecimal.ROUND_HALF_UP);
                    if (CommonConstant.REVIEW_TYPE_ORDINARY.equals(judgeType)) {
                        sportsProject.setAverageOrdinary(average);
                    } else {
                        sportsProject.setAverageSenior(average);
                    }
                    sportsProject.setProjectStatus(finishStatus);
                    sportsProject.setUpdateBy("admin");
                    sportsProject.setUpdateTime(new Date());
                    projectMapper.updateById(sportsProject);
                }
            }
        }
    }

    @Override
    public Result<?> applicationList(ReqListVO reqListVO, String username) {
        SysUser sysUser = sysUserMapper.getUserByName(username);
        List<SportProjectListVO> sportProjectListVOS = new ArrayList<>();
        List<SportsProject> list = getApplicationList(sysUser.getId(), reqListVO);
        if (null != list && list.size() > 0) {
            list.forEach(x -> {
                SportProjectListVO obj = new SportProjectListVO();
                BeanUtils.copyProperties(x, obj);
                if (null != x.getCaseType() && !"".equals(x.getCaseType())) {
                    obj.setCaseType(x.getCaseType());
                    obj.setCaseTypeName(getCaseTypeNameByCaseType(x.getCaseType()));
                }
                obj.setCaseName(x.getProjectName());
                obj.setName(x.getUserName());
                obj.setProjectId(x.getId());

                //当案例对应的是一线体育老师上传的案例时，先取视频数据，如果有视频，取视频快照，如果没有视频，则取对应的第一张图片，否则直接设置为空，前端显示默认图片
                if (CommonConstant.ROLE_TYPE_TE.equals(x.getRoleType())) {
                    obj.setSnapshotUrl(getSnapShotUrl(x.getId()));
                }
                sportProjectListVOS.add(obj);
            });
        }
        return Result.OK("success", sportProjectListVOS);
    }

    @Override
    public Result<?> sendMsgByEmail() {
        List<SendEmailLog> list = getSendEmailList(CommonConstant.LOG_TYPE_1);
        log.info("共计需要发送：{}条邮件数据！！！", list.size());
        String subject = "【中期提醒】2025活力校园优秀案例征集即将进入倒计时！7月6日截止申报";
        String content = ("尊敬的老师：<br>" +
                "<p>您好！2025年（第八届）活力校园优秀案例征集活动已收到全国教育工作者的热烈响应。" +
                "现温馨提醒您：<b>案例提交截止日期为2025年7月6日，距今仅剩1个月时间！</b>我们诚挚邀请您申报本届案例，" +
                "分享您在课堂教学、体育活动、校园文化建设、资源创新、家校社联动等方面的优秀实践，" +
                "也欢迎您将信息<b>转发推荐给身边同样投身体育教育的同行们。</b></p>" +
                "<p><b>征集对象：</b>本届案例申报共分四类，分别为优秀体育教师案例、优秀校长案例、优秀体育教研员案例、活力校园推广大使。" +
                "欢迎符合条件的教育工作者踊跃参与！</p>" +
                "<p><b>入选者将有机会：</b>获得海外交流培训机会（优秀案例负责人）、" +
                "获得连续三年项目支持与资源激励（推广大使）、入选案例将通过媒体宣传、教案展示等方式予以推广。</p>" +
                "<p><b>申报截止时间：2025年7月6日</b></p>" +
                "<p><b>申报入口及详细信息请登录：</b> <a href='https://www.huolixiaoyuan.com'>www.huolixiaoyuan.com</a></p>" +
                "<hr><br>" +
                "如有任何技术或流程问题，欢迎随时联系我们：<br>" +
                "联系电话：15800591257、19521251278（服务时间：工作日 9:00-19:00）<br>" +
                "联系邮箱：help@huolixiaoyuan.com<br>" +
                "官方客服微信：Nikehuolixiaoyuan<br>"+
                "<img src = 'https://nike-huolixiaoyuan.oss-rg-china-mainland.aliyuncs.com/upload/prod/20250606/活力校园官方客服微信_1749199925478.png'><br>"+
                "感谢您对“活力校园”项目的持续关注与支持！<br>" +
                "期待看到您的精彩案例！<br>" +
                "祝工作顺利、身心健康！<br><br>" +
                "<p><b>活力校园优秀案例征集活动办公室</b></p>" +
                "2025年6月");
        for (SendEmailLog sendEmailLog : list) {
            try {
                EmailUtil.commonSendEmail(sendEmailLog.getEmail(),subject, content);
                sendEmailLog.setSendStatus(1);
                updateSendEmailLog(sendEmailLog);
                Thread.sleep(3000);
            } catch (Exception e) {
                sendEmailLog.setSendStatus(2);
                updateSendEmailLog(sendEmailLog);
                e.printStackTrace();
            }
        }
        log.info("所有邮件发送完成");
        return Result.OK();
    }

    @Override
    public Result<?> sendMsgByTemplate() {
        List<SendEmailLog> list = getSendEmailList(CommonConstant.LOG_TYPE_2);
        log.info("共计需要发送：{}条短信数据！！！", list.size());
        for (SendEmailLog sendEmailLog : list) {
            try {
                SmsUtil.sendSmsByTemplate(sendEmailLog.getPhone());
                sendEmailLog.setSendMsgStatus(1);
                updateSendEmailLog(sendEmailLog);
                //5秒一条
                Thread.sleep(500);
            } catch (Exception e) {
                sendEmailLog.setSendMsgStatus(2);
                updateSendEmailLog(sendEmailLog);
                e.printStackTrace();
            }
        }
        log.info("所有短信发送完成");
        return Result.OK();
    }

    /**
     * top200评审后进入系数算法
     * @return
     */
    @Override
    public Result<?> getCoefficient() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        //获取当前年的TOP200数据
        List<SportsProject> top200List = getTop200ProjectList(year, null, 1);
        List<SportsProject> hisTeacherList = getTop200ProjectList(year, null, 0);
        List<SportsProject> hisSchoolList = getTop200ProjectList(year, CommonConstant.ROLE_TYPE_TE, 0);

        List<SportsProjectCoefficient> cfList = new ArrayList<>();

        for (SportsProject sportsProject : top200List) {
            SportsProjectCoefficient cf = new SportsProjectCoefficient();
            cf.setId(IdWorker.getIdStr());
            cf.setProjectId(sportsProject.getId());
            cf.setPhone(sportsProject.getCreateBy());
            cf.setProjectName(sportsProject.getProjectName());
            cf.setUserName(sportsProject.getUserName());

            BigDecimal averageSenior = sportsProject.getAverageSenior();
            cf.setAverageSenior(averageSenior);

            String userId = sportsProject.getUserId();
            cf.setUserId(userId);

            String schoolName = sportsProject.getSchoolName();
            cf.setSchoolName(sportsProject.getSchoolName());

            BigDecimal coefficientScore = averageSenior;
            long selfCnt = hisTeacherList.stream()
                    .filter(item -> item.getUserId().equals(userId))
                    .count();
            if(selfCnt > 0){
                // 入围一次总分*0.9,二次*0.8,三次*0.7 依此类推
                log.info("此老师:{}, 往年有{}次获奖", userId, selfCnt);
                coefficientScore = calCoefficient(coefficientScore, selfCnt, CommonConstant.USER_IDENTITY_1);
            }

            long schoolCnt = hisSchoolList.stream()
                    .filter(item -> item.getSchoolName().equals(schoolName) && !item.getUserId().equals(userId))
                    .count();
            if (schoolCnt > 0){
                // 入围一次总分*0.95,二次*0.85,三次*0.75 依此类推
                log.info("此老师所在学校:{}, 往年有{}次获奖", schoolName, schoolCnt);
                coefficientScore = calCoefficient(coefficientScore, schoolCnt, CommonConstant.USER_IDENTITY_2);
            }
            cf.setTeacherTopNum(Integer.parseInt(selfCnt + ""));
            cf.setSchoolTopNum(Integer.parseInt(schoolCnt + ""));
            cf.setCoefficientScore(coefficientScore);
            cfList.add(cf);
        }

        if (cfList != null && cfList.size() > 0){
            sportsProjectCoefficientMapper.batchInsert(cfList);
        }
        return Result.OK("success");
    }

    /**
     * 判断当前用户是否入围一线体育老师 top200
     * @param userId
     * @return
     */
    @Override
    public boolean checkIsTop200(String userId) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getUserId, userId);
        lambdaQueryWrapper.eq(SportsProject::getYear, year);
        lambdaQueryWrapper.eq(SportsProject::getIzTop200, CommonConstant.COMMON_STATUS_Y);
        lambdaQueryWrapper.eq(SportsProject::getRoleType, CommonConstant.ROLE_TYPE_TE);
        SportsProject sportsProject = sportsProjectMapper.selectOne(lambdaQueryWrapper);
        if (null != sportsProject){
            return true;
        }
        return false;
    }

    /**
     * 系统计算
     * @param score  原始分值
     * @param cnt    次数
     * @param type   类型 1-老师系数，2-学校系数
     * @return
     */
    public BigDecimal calCoefficient(BigDecimal score, long cnt, Integer type){
        if (type == 1) {
            if (cnt == 1) {
                return score.multiply(new BigDecimal(0.9));
            }
            if (cnt == 2) {
                return score.multiply(new BigDecimal(0.8));
            }
            if (cnt == 3) {
                return score.multiply(new BigDecimal(0.7));
            }
            if (cnt == 4) {
                return score.multiply(new BigDecimal(0.6));
            }
            if (cnt == 5) {
                return score.multiply(new BigDecimal(0.5));
            }
            if (cnt == 6) {
                return score.multiply(new BigDecimal(0.4));
            }
            if (cnt == 7) {
                return score.multiply(new BigDecimal(0.3));
            }
            if (cnt == 8) {
                return score.multiply(new BigDecimal(0.2));
            }
            if (cnt == 9) {
                return score.multiply(new BigDecimal(0.1));
            }
        } else {

            if (cnt == 1) {
                return score.multiply(new BigDecimal(0.95));
            }
            if (cnt == 2) {
                return score.multiply(new BigDecimal(0.85));
            }
            if (cnt == 3) {
                return score.multiply(new BigDecimal(0.75));
            }
            if (cnt == 4) {
                return score.multiply(new BigDecimal(0.65));
            }
            if (cnt == 5) {
                return score.multiply(new BigDecimal(0.55));
            }
            if (cnt == 6) {
                return score.multiply(new BigDecimal(0.45));
            }
            if (cnt == 7) {
                return score.multiply(new BigDecimal(0.35));
            }
            if (cnt == 8) {
                return score.multiply(new BigDecimal(0.25));
            }
            if (cnt == 9) {
                return score.multiply(new BigDecimal(0.15));
            }
            if (cnt == 10) {
                return score.multiply(new BigDecimal(0.05));
            }
        }
        return null;
    }

    public List<SportsProject> getTop200ProjectList(int year, String roleType, int type) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        if (type == 0){
            lambdaQueryWrapper.ne(SportsProject::getYear, year);
            lambdaQueryWrapper.eq(SportsProject::getIzWin, CommonConstant.COMMON_STATUS_Y);
        } else {
            lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_SENIOR);
            lambdaQueryWrapper.eq(SportsProject::getYear, year);
            lambdaQueryWrapper.eq(SportsProject::getIzTop200, CommonConstant.COMMON_STATUS_Y);
        }
        if (null != roleType) {
            lambdaQueryWrapper.eq(SportsProject::getRoleType, roleType);
        }
        return sportsProjectMapper.selectList(lambdaQueryWrapper);
    }


    public void updateSendEmailLog(SendEmailLog sendEmailLog){
        sendEmailLog.setUpdateTime(new Date());
        sendEmailLogMapper.updateById(sendEmailLog);
    }

    public List<SendEmailLog> getSendEmailList(Integer type){
        LambdaQueryWrapper<SendEmailLog> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (type == 1) {
            lambdaQueryWrapper.eq(SendEmailLog::getSendStatus, CommonConstant.COMMON_STATUS_N);
        }
        if (type == 2) {
            lambdaQueryWrapper.eq(SendEmailLog::getSendMsgStatus, CommonConstant.COMMON_STATUS_N);
        }
        return sendEmailLogMapper.selectList(lambdaQueryWrapper);
    }


    public List<SportsProject> getApplicationList(String userId, ReqListVO reqListVO) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
//        lambdaQueryWrapper.eq(SportsProject::getProjectStep, CommonConstant.PROJECT_STEP_FINISH);
        lambdaQueryWrapper.ne(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_PENDING);
        lambdaQueryWrapper.eq(SportsProject::getUserId, userId);
        int year;
        if (null != reqListVO.getYear() && !"".equals(reqListVO.getYear())) {
            year = reqListVO.getYear();
        } else {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
        }
        lambdaQueryWrapper.eq(SportsProject::getYear, year);
        if (!"".equals(reqListVO.getProjectName()) && null != reqListVO.getProjectName()) {
            lambdaQueryWrapper.like(SportsProject::getProjectName, reqListVO.getProjectName());
        }
        return projectMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 查询案例对应的申报推荐人列表信息
     *
     * @param projectId
     * @return
     */
    public List<SportsReference> getSportsReferences(String projectId) {
        LambdaQueryWrapper<SportsReference> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsReference::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsReference::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsReferenceMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 角色为一线体育老师或是校长时，需判断案例内容是否为空
     * @param caseReport
     * @param roleType
     * @return
     */
    public boolean checkCaseReportNull(SportsCaseReport caseReport, String roleType){
        boolean flag = false;
        if (CommonConstant.ROLE_TYPE_TE.equals(roleType) || CommonConstant.ROLE_TYPE_SM.equals(roleType)) {
            if(null == caseReport.getCaseContent() || "".equals(caseReport.getCaseContent())) {
                return flag;
            }
        }
        return true;
    }

    /**
     * 提交案例
     *
     * @param projectId
     * @param username
     * @return
     */
    @Override
    @Transactional
    public Result<?> submit(String projectId, String username) {
        //判断案例提报时间是否超出
        if (!checkOverSubmitTime()) {
            return Result.error("抱歉，不能超期提交案例！");
        }
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        SportsCaseReport caseReport = getCaseReportByProjectId(projectId);
        SportsPersonalInfo sportsPersonalInfo = getSportsPersonalInfoByProjectId(projectId);
        SportsProject sportsProject = projectMapper.selectById(projectId);
        boolean flag = false;
        if (null != caseReport) {
           flag = checkCaseReportNull(caseReport, sportsProject.getRoleType());
        } else if (sportsProject.getRoleType().equals(CommonConstant.ROLE_TYPE_PA)){
            flag = true;
        }

        if (!flag){
            return Result.error("案例申报书-案例正文内容不能为空，请填写后再提交！");
        } else {
            //当案例填报人角色为一线体育老师时，状态为未初审，需去重，其他角色暂时不去重
            if (CommonConstant.ROLE_TYPE_TE.equals(sportsProject.getRoleType())) {
                //案例初审状态为未初审
                sportsProject.setFirstAuditStatus(CommonConstant.PROJECT_FIRST_AUDIT_STATUS_PENDING);
            } else {
                sportsProject.setFirstAuditStatus(CommonConstant.PROJECT_FIRST_AUDIT_STATUS_FINISH);
            }

            String caseName = "";
            if (null == caseReport) {
                caseName = year + "年推广大使申报书";
            } else {
                if (null != caseReport.getCaseType() && !"".equals(caseReport.getCaseType())) {
                    sportsProject.setCaseType(caseReport.getCaseType());
                }
                caseName = caseReport.getCaseName();
            }
            sportsProject.setProjectName(caseName);
            sportsProject.setSchoolName(sportsPersonalInfo.getSchoolName());
            sportsProject.setUpdateBy(username);
            sportsProject.setUpdateTime(new Date());
            //默认为当前年
            sportsProject.setYear(year);
            //状态为待提交，则需将信息做加密处理，否则不需要处理
            if (CommonConstant.PROJECT_STATUS_PENDING.equals(sportsProject.getProjectStatus())) {
                //将用户信息加密
                //姓名
                if (null != sportsPersonalInfo.getName() && !"".equals(sportsPersonalInfo.getName())) {
                    sportsProject.setUserName(sportsPersonalInfo.getName());
                    String name = SensitiveInfoUtil.getEncodeData(sportsPersonalInfo.getName(), SensitiveEnum.ENCODE);
                    sportsPersonalInfo.setName(name);
                }
                //地址
                if (null != sportsPersonalInfo.getAddress() && !"".equals(sportsPersonalInfo.getAddress())) {
                    sportsPersonalInfo.setAddress(SensitiveInfoUtil.getEncodeData(sportsPersonalInfo.getAddress(), SensitiveEnum.ENCODE));
                }
                //身份证号
                if (null != sportsPersonalInfo.getIdNumber() && !"".equals(sportsPersonalInfo.getIdNumber())) {
                    sportsPersonalInfo.setIdNumber(SensitiveInfoUtil.getEncodeData(sportsPersonalInfo.getIdNumber(), SensitiveEnum.ENCODE));
                }
                //手机号
                if (null != sportsPersonalInfo.getPhone() && !"".equals(sportsPersonalInfo.getPhone())) {
                    sportsPersonalInfo.setPhone(SensitiveInfoUtil.getEncodeData(sportsPersonalInfo.getPhone(), SensitiveEnum.ENCODE));
                }
                //邮箱
                if (null != sportsPersonalInfo.getEmail() && !"".equals(sportsPersonalInfo.getEmail())) {
                    sportsPersonalInfo.setEmail(SensitiveInfoUtil.getEncodeData(sportsPersonalInfo.getEmail(), SensitiveEnum.ENCODE));
                }
            }
            sportsPersonalInfo.setUpdateTime(new Date());
            personalInfoMapper.updateById(sportsPersonalInfo);
            //案例提交状态为已提交
            sportsProject.setProjectStatus(CommonConstant.PROJECT_STATUS_SUBMIT);
            sportsProject.setProjectStep(CommonConstant.PROJECT_STEP_FINISH);
            sportsProject.setSubmitTime(new Date());
            projectMapper.updateById(sportsProject);
            return Result.OK("案例提交成功！");
        }
    }

    public boolean checkOverSubmitTime() {
        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysConfig::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SysConfig::getConfigType, CommonConstant.PROJECT_REVIEW_STATUS_PENDING);
        SysConfig sysConfig = sysConfigMapper.selectOne(lambdaQueryWrapper);
        Date now = new Date();
        Date endDate = sysConfig.getEndDate();
        int comparion = now.compareTo(endDate);
        if (comparion < 0) {
            return true;
        }
        return false;
    }

    public SportsPersonalInfo getSportsPersonalInfoByProjectId(String projectId) {
        LambdaQueryWrapper<SportsPersonalInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsPersonalInfo::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsPersonalInfo::getProjectId, projectId);
        return personalInfoMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public SportsProject getSportsProjectById(String projectId) {
        return projectMapper.selectById(projectId);
    }

    /**
     * 轮询将案例分配在不同省的评委
     */
    @Override
    public Result<?> projectAssignment(AssignmentReqVO reqVO, String username) {
        String judgeType = reqVO.getJudgeType();
        Integer year;
        if (null == reqVO.getYear()) {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
        } else {
            year = reqVO.getYear();
        }
        //获取待分配的案例列表
        List<CaseItemVO> caseItemVOS = getCaseItemList(reqVO.getJudgeType(), reqVO.getRoleType(), year, reqVO.getGroupType());
        //获取对应的评审员列表
        List<JudgeVO> judgeVOS = projectMapper.getJudgeUserId(reqVO.getJudgeType(), reqVO.getRoleType(), reqVO.getGroupName(), year);

        if (null == caseItemVOS){
            return Result.ok("没有可分配的案例！");
        }
        if (null == judgeVOS){
            return Result.ok("没有评审！");
        }
        log.info("----------待分配案例数量为：{}条，评审数量为：{}人", caseItemVOS.size(), judgeVOS.size());
        if (CommonConstant.REVIEW_DISPUTE_FIRST.equals(reqVO.getJudgeType()) || CommonConstant.REVIEW_DISPUTE_FINAL.equals(reqVO.getJudgeType())){
            //一个案例对应一个评审的分配方案
            assignmentJudge(caseItemVOS, judgeVOS, reqVO.getRoleType(),  judgeType, username);
        } else {
            //一个案例对应多个评审
            assignmentCase(caseItemVOS, judgeVOS, reqVO.getRoleType(), judgeType, username);
        }
        return Result.OK("案例分配完成！");
    }

    public List<CaseItemVO> getCaseItemList(String judgeType, String roleType, Integer year, Integer groupType) {
        List<CaseItemVO> caseItemVOS;
        switch (judgeType) {
            case CommonConstant.REVIEW_TYPE_ORDINARY:
                caseItemVOS = projectMapper.getAssignmentCaseItem(roleType, year, groupType);
                break;
            case CommonConstant.REVIEW_TYPE_SENIOR:
                caseItemVOS = projectMapper.getSeniorAssignmentCaseItem(roleType, year);
                break;
            case CommonConstant.REVIEW_DISPUTE_FIRST:
                caseItemVOS = projectMapper.getDisputeAssignmentCaseItem(roleType, year, groupType);
                break;
            case CommonConstant.REVIEW_DISPUTE_FINAL:
                caseItemVOS = projectMapper.getFinalAssignmentCaseItem(roleType, year, null);
                break;
            default:
                caseItemVOS = null;
        }
        return caseItemVOS;
    }

    /**
     * 一个案例对应多个评审， 并且进行平均分配
     *
     * @param caseTeItemVOS
     * @param judgeVOS
     * @param judgeType
     * @param username
     */
    public void assignmentCase(List<CaseItemVO> caseTeItemVOS, List<JudgeVO> judgeVOS, String roleType, String judgeType, String username) {
        Map<CaseItemVO, List<JudgeVO>> assignmentResult = new HashMap<>();
        Map<JudgeVO, Integer> assignmentCount = new HashMap<>();
        int judgeNum = getJudgeNumByRoleType(roleType);
        judgeVOS.forEach(reviewer -> assignmentCount.put(reviewer, 0));
        for (CaseItemVO currentCase : caseTeItemVOS) {
            String caseProvince = currentCase.getProvince();
            List<JudgeVO> candidates = judgeVOS.stream()
                    .filter(r -> !r.getProvince().equals(caseProvince))
                    .collect(Collectors.toList());

            if (candidates.size() < judgeNum) {
                log.error("案例省份 {}  无法分配足够评审。", caseProvince);
                candidates = judgeVOS;
                log.info("由于评审数据不够，只能分配同样的省份，进行案例的继续分配");
//                continue;
            }
//            else {
//                candidates = judgeVOS;
//                log.info("继续分配案例");
//            }

            // 按分配次数分组并随机排序同次数的评审
            Map<Integer, List<JudgeVO>> reviewersByCount = new HashMap<>();
            candidates.forEach(r -> {
                int count = assignmentCount.get(r);
                reviewersByCount.computeIfAbsent(count, k -> new ArrayList<>()).add(r);
            });

            List<Integer> sortedCounts = reviewersByCount.keySet().stream()
                    .sorted()
                    .collect(Collectors.toList());

            List<JudgeVO> shuffledCandidates = new ArrayList<>();
            sortedCounts.forEach(count -> {
                List<JudgeVO> group = new ArrayList<>(reviewersByCount.get(count));
                Collections.shuffle(group); // 随机打乱同次数的组
                shuffledCandidates.addAll(group);
            });

            // 选择前三个未被分配到当前案例的评审
            List<JudgeVO> selected = new ArrayList<>();
            for (JudgeVO reviewer : shuffledCandidates) {
                if (selected.size() >= judgeNum) {
                    break;
                }
                // 检查该评审是否已被分配到当前案例（防止重复分配）
                if (!selected.contains(reviewer)) {
                    selected.add(reviewer);
                }
            }

            if (selected.size() < judgeNum) {
                log.error("案例省份 {}  无法分配足够评审。", caseProvince);
                continue;
            }

            assignmentResult.put(currentCase, new ArrayList<>(selected));

            selected.forEach(r -> assignmentCount.put(r, assignmentCount.get(r) + 1));
        }

        // 输出各评审分配次数
        assignmentCount.forEach((r, count) ->
                log.info("各评审:{}, 分配次数为：{}次", r.getJudgeUserId(), count)
        );
        // 输出分配结果
        assignmentResult.forEach((c, rs) -> {
            log.info("案例： {}, 所在省份：{}，  分配评审为: {} ", c.getCaseName(), c.getProvince(),
                    rs.stream().map(JudgeVO::getJudgeUserId).collect(Collectors.joining(", ")));
            //将分配好的案例对应的评审写入案例评审分配表
            initProjectReview(c, rs, judgeType, username, roleType);
        });
    }


    /**
     * 只需要给案例分配一个评审的分配方案
     *
     * @param caseTeItemVOS
     * @param judgeVOS
     * @param judgeType
     */
    public void assignmentJudge(List<CaseItemVO> caseTeItemVOS, List<JudgeVO> judgeVOS, String roleType, String judgeType, String username) {
        int judgeNum = 1;
        for (CaseItemVO caseItem : caseTeItemVOS) {
            List<JudgeVO> assignedReviewers = new ArrayList<>();
            //过滤掉同省市评委
            List<JudgeVO> availableReviewers = judgeVOS.stream()
                    .filter(judgeVO -> !judgeVO.getProvince().equals(caseItem.getProvince()))
                    .collect(Collectors.toList());
            if (CommonConstant.REVIEW_DISPUTE_FIRST.equals(judgeType) || CommonConstant.REVIEW_DISPUTE_FINAL.equals(judgeType)) {
                //查出当前案例对应的过往评审
                List<JudgeVO> hisJudgeIds = getHisJudgeIdsByProjectId(caseItem.getProjectId());
                //过滤掉过往评审
                List<JudgeVO> resultList = Stream.concat(availableReviewers.stream(), hisJudgeIds.stream())
                        .collect(Collectors.groupingBy(JudgeVO::getJudgeUserId, Collectors.counting()))
                        .entrySet().stream()
                        .filter(e -> e.getValue() == judgeNum)
                        .map(e -> e.getKey())
                        .map(judgeUserId -> Stream.concat(availableReviewers.stream(), hisJudgeIds.stream()).filter(p -> p.getJudgeUserId().equals(judgeUserId)).findFirst().get())
                        .collect(Collectors.toList());
                //去除省份为空的对象
                List<JudgeVO> pendingVOs = resultList.stream().filter(judgeVO -> judgeVO.getProvince() != null).collect(Collectors.toList());
                //打乱顺序（随机排序）
                Collections.shuffle(pendingVOs);
                JudgeVO judgeVO = pendingVOs.get(0);
                log.info("给当前案例:{},分配的评审是：{}", caseItem.getCaseName(), judgeVO.getJudgeUserId());
                assignedReviewers.add(pendingVOs.get(0));
            } else {
                //打乱顺序（随机排序）
                Collections.shuffle(availableReviewers);
                List<JudgeVO> selectJudgeVos = availableReviewers.subList(0, judgeNum);
                assignedReviewers.add(selectJudgeVos.get(0));
            }
            //写入案例评审表
            initProjectReview(caseItem, assignedReviewers, judgeType, username, roleType);
        }
    }

    public List<JudgeVO> getHisJudgeIdsByProjectId(String projectId) {
        List<JudgeVO> judgeVOS = new ArrayList<>();
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        List<SportsProjectReview> reviews = sportsProjectReviewMapper.selectList(lambdaQueryWrapper);
        reviews.forEach(x -> {
            JudgeVO judgeVO = new JudgeVO();
            judgeVO.setJudgeUserId(x.getJudgeUserId());
            judgeVO.setGroupId(x.getGroupId());
            judgeVOS.add(judgeVO);
        });
        return judgeVOS;
    }

    /**
     * nike团队---查看分配列表 /入围案例分配列表
     * judgeType 1-普通专家，2-资深专家
     *
     * @param reqVO
     * @return
     */
    @Override
    public Result<RespProjectAssignmentListVO> getProjectAssignList(ReqProjectAssignmentListVO reqVO) {
        RespProjectAssignmentListVO respVO = new RespProjectAssignmentListVO();
        List<ProjectAssignmentListVO> assignList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> paraMap = new HashMap<>();
        int unAssignTotal, assignTotal;
        int offset = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
        map.put("offset", offset);
        map.put("limit", reqVO.getPageSize());
        map.put("projectName", reqVO.getProjectName());
        map.put("assignStatus", reqVO.getAssignStatus());
        map.put("roleType", reqVO.getRoleType());
        Integer year;
        if (null == reqVO.getYear()) {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
        } else {
            year = reqVO.getYear();
        }
        paraMap.put("year", year);
        map.put("year", year);
        // 普通专家分配列表组装
        if (CommonConstant.REVIEW_TYPE_ORDINARY.equals(reqVO.getJudgeType())) {
            paraMap.put("projectName", reqVO.getProjectName());
            paraMap.put("assignStatus", CommonConstant.UN_ASSIGN_STATUS);
            paraMap.put("roleType", reqVO.getRoleType());
            //未分配总数
            unAssignTotal = projectMapper.getAssignTotal(paraMap);
            //已分配总数
            paraMap.put("assignStatus", CommonConstant.ASSIGN_STATUS);
            assignTotal = projectMapper.getAssignTotal(paraMap);
            if (CommonConstant.ASSIGN_STATUS.equals(reqVO.getAssignStatus())) {
                assignList = projectMapper.getAssignmentCaseItemByPage(map);
                assignList = packageAssignList(assignList, CommonConstant.ASSIGN_STATUS, reqVO.getJudgeType());
            } else {
                assignList = projectMapper.getAssignmentCaseItemByPage(map);
                assignList.forEach(x -> {
                    x.setAssignStatus(CommonConstant.UN_ASSIGN_STATUS);
                });
            }
        } else {
            //资深专家分配列表组装
            paraMap.put("projectName", reqVO.getProjectName());
            paraMap.put("assignStatus", CommonConstant.UN_ASSIGN_STATUS);
            //未分配总数
            unAssignTotal = getSeniorAuditTotal(reqVO.getProjectName(), CommonConstant.UN_ASSIGN_STATUS, year, reqVO.getRoleType());
            //已分配总数
            paraMap.put("assignStatus", CommonConstant.ASSIGN_STATUS);
            assignTotal = getSeniorAuditTotal(reqVO.getProjectName(), CommonConstant.ASSIGN_STATUS, year, reqVO.getRoleType());
            if (CommonConstant.UN_ASSIGN_STATUS.equals(reqVO.getAssignStatus())) {
                assignList = projectMapper.getSeniorUnAssginListByPage(map);
                assignList.forEach(x -> {
                    x.setAssignStatus(CommonConstant.UN_ASSIGN_STATUS);
                });
            } else {
                assignList = packageAssignList(projectMapper.getSeniorAssignListByPage(map), CommonConstant.ASSIGN_STATUS, reqVO.getJudgeType());
            }
        }
        respVO.setAssignTotal(assignTotal);
        respVO.setUnAssignTotal(unAssignTotal);
        respVO.setAssignList(assignList);
        respVO.setPageNo(reqVO.getPageNo());
        respVO.setPageSize(reqVO.getPageSize());
        return Result.OK("success", respVO);
    }

    /**
     * 组装 普通评审或是资深评审人，用List<String>将评审人名写入列表对应字段
     *
     * @param list
     * @return
     */
    public List<ProjectAssignmentListVO> packageAssignList(List<ProjectAssignmentListVO> list, String assignStatus, String judgeType) {
        if (null != list && list.size() > 0) {
            List<String> ids = new ArrayList<>();
            list.forEach(x -> {
                ids.add(x.getProjectId());
                //将分配状态更新
                if (CommonConstant.ASSIGN_STATUS.equals(assignStatus)) {
                    x.setAssignStatus(CommonConstant.ASSIGN_STATUS);
                } else {
                    x.setAssignStatus(CommonConstant.UN_ASSIGN_STATUS);
                }
            });
            if (null != ids && ids.size() > 0) {
                //查找当前案例对应的评审
                List<AssignJudgeUserList> judgeUserLists = projectMapper.getAssignJudgeList(ids, judgeType);
                for (int i = 0; i < list.size(); i++) {
                    List<JudgeScoreVO> judgeScoreVOS = new ArrayList<>();
                    for (int j = 0; j < judgeUserLists.size(); j++) {
                        if (list.get(i).getProjectId().equals(judgeUserLists.get(j).getProjectId())) {
                            JudgeScoreVO judgeScoreVO = new JudgeScoreVO();
                            judgeScoreVO.setJudgeUserName(judgeUserLists.get(j).getJudgeName());
                            judgeScoreVO.setScore(judgeUserLists.get(j).getScore());
                            judgeScoreVOS.add(judgeScoreVO);
                        }
                    }
                    list.get(i).setJudgeScoreVOList(judgeScoreVOS);
                }
            }
        }
        return list;
    }

    public List<AuditScoreVO> packageAuditScoreList(List<AuditScoreVO> list, List<String> ids, String judgeType) {
        if (null != ids && ids.size() > 0) {
            //查找当前案例对应的普通评审
            List<AssignJudgeUserList> judgeUserLists = projectMapper.getAssignJudgeList(ids, judgeType);
            for (int i = 0; i < list.size(); i++) {
                List<JudgeScoreVO> judgeScoreVOS = new ArrayList<>();
                for (int j = 0; j < judgeUserLists.size(); j++) {
                    if (list.get(i).getProjectId().equals(judgeUserLists.get(j).getProjectId())) {
                        JudgeScoreVO judgeScoreVO = new JudgeScoreVO();
                        judgeScoreVO.setScore(judgeUserLists.get(j).getScore());
                        judgeScoreVO.setJudgeUserName(judgeUserLists.get(j).getJudgeName());
                        judgeScoreVOS.add(judgeScoreVO);
                    }
                }
                list.get(i).setJudgeScoreVOS(judgeScoreVOS);
            }
        }
        return list;
    }

    /**
     * 初始化案例评审表
     *
     * @param caseItem       案例
     * @param assignedJudges 评审员列表三个
     * @param judgeType      评委类型 1-普通专家，2-资深专家 3-初审争议，4-终审争议
     */
    @Transactional
    public void initProjectReview(CaseItemVO caseItem, List<JudgeVO> assignedJudges, String judgeType, String username, String roleType) {
        assignedJudges.forEach(x -> {
            SportsProjectReview projectReview = new SportsProjectReview();
            projectReview.setCaseName(caseItem.getCaseName());
            projectReview.setProjectId(caseItem.getProjectId());
            if (null != caseItem.getCaseType() && !"".equals(caseItem.getCaseType())) {
                projectReview.setCaseType(caseItem.getCaseType());
            }
            projectReview.setJudgeUserId(x.getJudgeUserId());
            projectReview.setReviewer(caseItem.getReviewer());
            projectReview.setSchoolName(caseItem.getSchoolName());
            projectReview.setReviewType(judgeType);
            projectReview.setGroupId(x.getGroupId());
            projectReview.setCreateBy("admin");
            projectReview.setRoleType(roleType);
            projectReview.setCreateTime(new Date());
            //评审列表中的状态为待评审
            projectReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_PENDING);
            sportsProjectReviewMapper.insert(projectReview);

            //当为二审时，需要新增国际行评审数据
            if (CommonConstant.REVIEW_TYPE_SENIOR.equals(judgeType)) {
                SportsProjectReview internationTravelReview = new SportsProjectReview();
                BeanUtils.copyProperties(projectReview, internationTravelReview);
                internationTravelReview.setId(IdWorker.getIdStr());
                internationTravelReview.setReviewType(CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
                sportsProjectReviewMapper.insert(internationTravelReview);
            }
            log.info("案例id:{},被分配给了用户id为：{}的用户", caseItem.getProjectId(), x.getJudgeUserId());
        });
        //案例主表状态设置为待评审
        SportsProject sportsProject = projectMapper.selectById(caseItem.getProjectId());
        String projectStatus = "";
        if (CommonConstant.REVIEW_DISPUTE_FIRST.equals(judgeType)) {
            projectStatus = CommonConstant.PROJECT_STATUS_DISPUTE_AUDITING_ORDINARY;
        }
        if (CommonConstant.REVIEW_DISPUTE_FINAL.equals(judgeType)) {
            projectStatus = CommonConstant.PROJECT_STATUS_DISPUTE_AUDITING_SENIOR;
        }
        if (CommonConstant.REVIEW_TYPE_ORDINARY.equals(judgeType)) {
            projectStatus = CommonConstant.PROJECT_STATUS_AUDITING_ORDINARY;
        }
        if (CommonConstant.REVIEW_TYPE_SENIOR.equals(judgeType)) {
            projectStatus = CommonConstant.PROJECT_STATUS_AUDITING_SENIOR;
            sportsProject.setIzInternationalTravel(CommonConstant.COMMON_STATUS_Y);
        }
        sportsProject.setProjectStatus(projectStatus);
        sportsProject.setUpdateBy(username);
        sportsProject.setUpdateTime(new Date());
        projectMapper.updateById(sportsProject);
    }

    public static boolean checkDifference(int a, int b, int c) {
        // 检查所有可能的两个数之间的差值是否都大于等于2
        if (Math.abs(a - b) >= 2 || Math.abs(a - c) >= 2 || Math.abs(b - c) >= 2) {
            return true;
        }
        return false;
    }


    /**
     * 检查所有人员评分等级是否相差大于等于2级
     * @param ratings 每个人的评分等级数组
     * @return 如果存在任意两人等级差≥2返回false，否则返回true
     */
    public static boolean checkAllRatingDifferences(int[] ratings) {
        if (ratings == null || ratings.length < 2) {
            // 如果人数少于2，无法比较，默认返回true
            return true;
        }

        // 先排序可以简化比较
//        Arrays.sort(ratings);
//
//        // 检查排序后的相邻元素（因为排序后最大差一定在相邻元素中）
//        for (int i = 0; i < ratings.length - 1; i++) {
//            if (ratings[i + 1] - ratings[i] >= 2) {
//                return false;
//            }
//        }
//
//        return true;

        //或者不排序，直接双重循环比较所有组合
        for (int i = 0; i < ratings.length; i++) {
            for (int j = i + 1; j < ratings.length; j++) {
                if (Math.abs(ratings[i] - ratings[j]) >= 3) {
                    return false;
                }
            }
        }
        return true;
    }



    public static void main(String[] args) {
        int[] ratings = {1, 3, 2};
        System.out.println(checkAllRatingDifferences(ratings));
    }

    public boolean allDifferencesGreaterThan3(List<SportsProjectReview> reviews) {
        boolean allDifferencesGreaterThanThree = true;
        List<BigDecimal> scores = reviews.stream().map(item -> item.getScore()).collect(Collectors.toList());

        String disputeScore = sysDictMapper.getDictItemName(CommonConstant.DISPUTE_SCORE, "");
        BigDecimal score = new BigDecimal(disputeScore);

        for (int i = 0; i < scores.size(); i++) {
            for (int j = i + 1; j < scores.size(); j++) {
                BigDecimal diff = scores.get(i).subtract(scores.get(j));
                if (diff.compareTo(score) <= 0) {
                    allDifferencesGreaterThanThree = false;
                    break; // 可以选择跳出内部循环，或者根据需要保留以检查所有组合
                }
            }
            if (!allDifferencesGreaterThanThree) {
                break; // 如果发现不符合条件，可以跳出外部循环，根据需要保留此行或注释掉以检查所有组合
            }
        }
        return true; // 所有差值都大于3，返回true
    }

    @Override
    public Result<RespFirstAuditListVO> list(ReqListVO reqVO) {
        RespFirstAuditListVO respFirstAuditListVO = new RespFirstAuditListVO();
        Map<String, Object> map = new HashMap<>();
        int offset = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
        map.put("offset", offset);
        map.put("limit", reqVO.getPageSize());
        map.put("projectName", reqVO.getProjectName());
        if (null != reqVO.getRoleType() && !"".equals(reqVO.getRoleType())) {
            map.put("roleType", reqVO.getRoleType());
        } else {
            map.put("roleType", null);
        }
        map.put("caseType", reqVO.getCaseType());
        int year;
        if (null != reqVO.getYear() && !"".equals(reqVO.getYear())) {
            year = reqVO.getYear();
        } else {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
            reqVO.setYear(year);
        }
        map.put("year", year);
        map.put("firstAuditStatus", reqVO.getFirstAuditStatus());
        List<SportProjectListVO> list = projectMapper.getFirstAuditList(map);

        //从数据字典中取出去重比率
        String repetitonRate = sysDictMapper.getDictItemName(CommonConstant.REPETITION_RATE_DICT_CODE, "");
        BigDecimal rate = new BigDecimal(repetitonRate);
        if (null != list && list.size() > 0) {
            list.forEach(x -> {
                //当案例对应的是一线体育老师上传的案例时，先取视频数据，如果有视频，取视频快照，如果没有视频，则取对应的第一张图片，否则直接设置为空，前端显示默认图片
                if (CommonConstant.ROLE_TYPE_TE.equals(x.getRoleType())) {
                    x.setSnapshotUrl(getSnapShotUrl(x.getProjectId()));
                }
                x.setName(SensitiveInfoUtil.getDecodeData(x.getName()));
                if (null != x.getRepetitionRate() || "".equals(x.getRepetitionRate())){
                    BigDecimal repetitionRate = new BigDecimal(x.getRepetitionRate());
                    BigDecimal hundred = new BigDecimal("100");
                    x.setRepetitionRate(repetitionRate.multiply(hundred).toString());
                }
//                log.info("参评人===={}", x.getName());

                // 展示重复率的时候，当重复率没有超出固定值，则直接除以3 显示，用户查看时美观点
//                if (null != x.getRepetitionRate() && !"".equals(x.getRepetitionRate())){
//                    BigDecimal factRate = new BigDecimal(x.getRepetitionRate());
//                    if (factRate.compareTo(rate) < 0) {
//                        factRate = factRate.divide(BigDecimal.valueOf(3), 2, RoundingMode.HALF_UP);
////                        factRate = factRate.divide(new BigDecimal("3.00")).setScale(2, BigDecimal.ROUND_HALF_UP);
//                        log.info("factRate:{}", factRate);
//                    }
//                    x.setRepetitionRate(factRate.toString());
//                }
            });
        }
        respFirstAuditListVO.setAuditVOList(list);

        int allTotal = this.getFirstAuditStatusTotal(null, reqVO);
        //未查重案例总数
        int pendingTotal = this.getFirstAuditStatusTotal(CommonConstant.PROJECT_FIRST_AUDIT_STATUS_PENDING, reqVO);

        //已通过案例总数
        int finishTotal = this.getFirstAuditStatusTotal(CommonConstant.PROJECT_FIRST_AUDIT_STATUS_FINISH, reqVO);

        //已淘汰案例总数
        int outTotal = this.getFirstAuditStatusTotal(CommonConstant.PROJECT_FIRST_AUDIT_STATUS_OUT, reqVO);

        respFirstAuditListVO.setAllTotal(allTotal);
        respFirstAuditListVO.setPendingTotal(pendingTotal);
//        respFirstAuditListVO.setUnPassTotal(unPassTotal);
        respFirstAuditListVO.setFinishTotal(finishTotal);
        respFirstAuditListVO.setOutTotal(outTotal);
        respFirstAuditListVO.setPageNo(reqVO.getPageNo());
        respFirstAuditListVO.setPageSize(reqVO.getPageSize());
        return Result.OK("success", respFirstAuditListVO);
    }

    public int getSeniorAuditTotal(String projectName, String status, Integer year, String roleType) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getIzTop200, CommonConstant.COMMON_STATUS_Y);
        lambdaQueryWrapper.eq(SportsProject::getYear, year);
        if (null != roleType && !"".equals(roleType)) {
            lambdaQueryWrapper.eq(SportsProject::getRoleType, roleType);
        }
        if (!"".equals(projectName) && null != projectName) {
            lambdaQueryWrapper.like(SportsProject::getProjectName, projectName);
        }
        if (CommonConstant.ASSIGN_STATUS.equals(status)) {
            lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_AUDITING_SENIOR);
        } else {
            lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_ORDINARY);
        }
        return projectMapper.selectList(lambdaQueryWrapper).size();
    }

    public int getFirstAuditStatusTotal(String firstAuditStatus, ReqListVO reqVO) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.isNotNull(SportsProject::getSubmitTime);
        lambdaQueryWrapper.eq(SportsProject::getProjectStep, CommonConstant.PROJECT_STEP_FINISH);
        if (null != reqVO.getProjectName() && !"".equals(reqVO.getProjectName())) {
            lambdaQueryWrapper.and(wq -> wq.like(SportsProject::getProjectName, reqVO.getProjectName()).or().eq(SportsProject::getUserName, reqVO.getProjectName()));
        }
        if (null != firstAuditStatus && !"".equals(firstAuditStatus)) {
            lambdaQueryWrapper.eq(SportsProject::getFirstAuditStatus, firstAuditStatus);
        }
        if (null != reqVO.getYear() && !"".equals(reqVO.getYear())) {
            lambdaQueryWrapper.eq(SportsProject::getYear, reqVO.getYear());
        }
        if (null != reqVO.getCaseType() && !"".equals(reqVO.getCaseType())) {
            lambdaQueryWrapper.eq(SportsProject::getCaseType, reqVO.getCaseType());
        }
        if (null != reqVO.getRoleType() && !"".equals(reqVO.getRoleType())) {
            lambdaQueryWrapper.eq(SportsProject::getRoleType, reqVO.getRoleType());
        } else {
            List<String> roleTypes = new ArrayList<>();
            roleTypes.add(CommonConstant.ROLE_TYPE_PA);
            roleTypes.add(CommonConstant.ROLE_TYPE_SR);
            roleTypes.add(CommonConstant.ROLE_TYPE_SM);
            lambdaQueryWrapper.in(SportsProject::getRoleType, roleTypes);
        }
        List<SportsProject> list = projectMapper.selectList(lambdaQueryWrapper);
        if (null != list && list.size() > 0) {
            return list.size();
        }
        return 0;
    }

    /**
     * 获取案例对应的视频快照url
     *
     * @param projectId
     * @return
     */
    public String getSnapShotUrl(String projectId) {
        log.info("开始获取案例对应的快照或图片=== {}", projectId);
        List<OssFile> list = projectMapper.getSnapShotUrl(projectId, CommonConstant.OSS_FILE_TYPE_VIDEO);
        String snapshotUrl = "";
        if (null != list && list.size() > 0 && !"".equals(list.get(0).getSnapshot())) {
            snapshotUrl = list.get(0).getSnapshot();
        } else {
            List<OssFile> list1 = projectMapper.getSnapShotUrl(projectId, CommonConstant.OSS_FILE_TYPE_FILE);
            if (null != list1 && list1.size() > 0) {
                Optional<OssFile> min = list1.stream().min(Comparator.comparing(OssFile::getCreateTime));
                snapshotUrl = min.orElse(null).getSnapshot();
            }
        }
        return snapshotUrl;
    }

    @Override
    public Result<?> getUnSubmitDocList(int pageNo, int pageSize) {
        RespUnsubmitDocListVO unsubmitDocListVO = new RespUnsubmitDocListVO();
        Map<String, Object> map = new HashMap<>();
        int offset = (pageNo - 1) * pageSize;
        map.put("offset", offset);
        map.put("limit", pageSize);
        List<SportProjectListVO> list = projectMapper.getUnSubmitDocList(map);
        int total = projectMapper.getUnSubmitDocTotal(map);
        unsubmitDocListVO.setPageNo(pageNo);
        unsubmitDocListVO.setPageSize(pageSize);
        unsubmitDocListVO.setTotal(total);
        unsubmitDocListVO.setListVOS(list);
        return Result.OK("查询未提交资质文件的案例列表成功！", unsubmitDocListVO);
    }

    @Override
    public Result<String> sendSMSToApply(List<String> ids) {
        Result<String> result = new Result<>();
        //根据IDS查询出对应的案例信息及用户手机号集合
        List<ProjectApplyInfoVO> list = projectMapper.getProjectApplyInfo(ids);
        boolean b = false;
        if (null != list && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                ProjectApplyInfoVO projectApplyInfoVO = list.get(i);
                //发送短信
                JSONObject obj = new JSONObject();
                obj.put("projectName", projectApplyInfoVO.getProjectName());
                try {
                    b = DySmsHelper.sendSms(projectApplyInfoVO.getPhone(), obj, DySmsEnum.PROJECT_UNSUBMIT_QUALIFICATION_DOC_CODE);
                    if (b == false) {
                        result.setMessage("短信发送失败,请稍后重试！");
                        result.setSuccess(false);
                        return result;
                    }
                } catch (ClientException e) {
                    e.printStackTrace();
                    result.error500("短信接口未配置，请联系管理员！");
                    return result;
                }
            }
        }
        result.setSuccess(true);
        result.setMessage("短信发送成功！");
        return result;
    }

    /**
     * 案例淘汰/通过
     *
     * @param operationVO
     * @param username
     * @return
     */
    @Override
    public Result<?> operation(OperationVO operationVO, String username) {
        //判断当前传入的案例列表中是否存在有争议的案例
        int num = projectMapper.checkDispute(operationVO.getIds(), operationVO.getActionType(), operationVO.getRoleType());
        if (num > 0) {
            return Result.OK("有争议的案例不能被操作为入围！");
        }
        int i = projectMapper.updateProjectStatus(username, operationVO.getIds(), operationVO.getActionType());
        if (i > 0) {
            //发短信通知获奖 todo
            return Result.OK("案例操作成功！");
        }
        return Result.error("案例操作失败！");
    }

    /**
     * 争议案例列表
     *
     * @param reqVO
     * @return
     */
    @Override
    public Result<RespDisputeListVO> getDisputeList(DisputeListReqVO reqVO) {
        RespDisputeListVO disputeListVO = new RespDisputeListVO();
        List<ProjectAssignmentListVO> list = new ArrayList<>();
        List<ProjectAssignmentListVO> assignList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        int offset = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
        map.put("offset", offset);
        map.put("limit", reqVO.getPageSize());
        map.put("projectName", reqVO.getProjectName());
        map.put("queryStatus", reqVO.getQueryStatus());
        Integer year;
        if (null != reqVO.getYear() && !"".equals(reqVO.getYear())) {
            year = Integer.valueOf(reqVO.getYear());
        } else {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
            reqVO.setYear(year);
        }
        map.put("year", year);
        //初审争议案例
        if (CommonConstant.DISPUTE_FIRST.equals(reqVO.getQueryStatus())) {
            //未分配
            list = projectMapper.getDisputeFirstList(map);
            list = packageAssignList(list, CommonConstant.UN_ASSIGN_STATUS, CommonConstant.REVIEW_TYPE_ORDINARY);
            //已分配
            map.put("queryStatus", CommonConstant.DISPUTE_FISRT_TIME);
            assignList = projectMapper.getDisputeFirstList(map);
            assignList = packageAssignList(assignList, CommonConstant.ASSIGN_STATUS, CommonConstant.REVIEW_TYPE_ORDINARY);

        }
        //终审争议案例
        if (CommonConstant.DISPUTE_SECOND.equals(reqVO.getQueryStatus())) {
            //未分配
            list = projectMapper.getDisputeFirstList(map);
            list = packageAssignList(list, CommonConstant.UN_ASSIGN_STATUS, CommonConstant.REVIEW_TYPE_SENIOR);
            //已分配
            map.put("queryStatus", CommonConstant.DISPUTE_SECOND_TIME);
            assignList = projectMapper.getDisputeFirstList(map);
            assignList = packageAssignList(assignList, CommonConstant.ASSIGN_STATUS, CommonConstant.REVIEW_TYPE_SENIOR);
        }

        //初审案例待分配争议总数
        Integer firstDisputeTotal = getDisputeFirstTotal(reqVO.getProjectName(), reqVO.getYear(), null);
        //初审案例已分配总数
        Integer assignFirstDisputeTotal = getAssignDisputeTotal(reqVO.getProjectName(), reqVO.getYear(), CommonConstant.DISPUTE_FIRST);
        //入围案例待分配争议总数
        Integer top200DisputeTotal = getDisputeFirstTotal(reqVO.getProjectName(), reqVO.getYear(), CommonConstant.COMMON_STATUS_Y);
        //入围案例已分配总数
        Integer assignTop200DisputeTotal = getAssignDisputeTotal(reqVO.getProjectName(), reqVO.getYear(), CommonConstant.DISPUTE_SECOND);

        disputeListVO.setPageNo(reqVO.getPageNo());
        disputeListVO.setPageSize(reqVO.getPageSize());
        disputeListVO.setDisputeList(list);
        disputeListVO.setAssignDisputeList(assignList);
        disputeListVO.setFirstDisputeTotal(firstDisputeTotal);
        disputeListVO.setAssignFirstDisputeTotal(assignFirstDisputeTotal);
        disputeListVO.setTop200DisputeTotal(top200DisputeTotal);
        disputeListVO.setAssignTop200DisputeTotal(assignTop200DisputeTotal);
        return Result.OK("success", disputeListVO);
    }

    public Integer getAssignDisputeTotal(String projectName, Integer year, String queryStatus) {
        LambdaQueryWrapper<SportsProject> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        queryWrapper.eq(SportsProject::getYear, year);
        queryWrapper.eq(SportsProject::getFirstAuditStatus, CommonConstant.PROJECT_FIRST_AUDIT_STATUS_FINISH);
        queryWrapper.eq(SportsProject::getProjectStep, CommonConstant.PROJECT_STEP_FINISH);
        queryWrapper.eq(SportsProject::getIzDispute, CommonConstant.COMMON_STATUS_Y);
        if (CommonConstant.DISPUTE_FIRST.equals(queryStatus)) {
            queryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_DISPUTE_AUDITING_ORDINARY);
//            queryWrapper.or().isNotNull(SportsProject::getFirstDisputeScore);
        } else {
            queryWrapper.eq(SportsProject::getIzTop200, CommonConstant.COMMON_STATUS_Y);
            queryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_DISPUTE_AUDITING_SENIOR);
//            queryWrapper.or().isNotNull(SportsProject::getFinalDisputeScore);
        }
        if (null != projectName && !"".equals(projectName)) {
            queryWrapper.like(SportsProject::getProjectName, projectName);
        }
        List<SportsProject> list = projectMapper.selectList(queryWrapper);
        if (list != null && list.size() > 0) {
            return list.size();
        }
        return 0;
    }

    @Override
    public Result<AuditScoreListRespVO> getFirstAuditScoreList(AuditScoreListReqVO reqVO) {
        List<AuditScoreVO> list;
        AuditScoreListRespVO auditScoreListRespVO = new AuditScoreListRespVO();
        Map<String, Object> map = new HashMap<>();
        int offset = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
        map.put("offset", offset);
        map.put("limit", reqVO.getPageSize());
        map.put("projectName", reqVO.getProjectName());
        map.put("caseType", reqVO.getCaseType());
        map.put("roleType", reqVO.getRoleType());
        Integer year;
        if (null != reqVO.getYear() && !"".equals(reqVO.getYear())) {
            year = Integer.valueOf(reqVO.getYear());
        } else {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
            reqVO.setYear(year);
        }
        map.put("year", year);

        if (CommonConstant.DISPUTE_FIRST.equals(reqVO.getStatus())) {
            map.put("izTop200", CommonConstant.COMMON_STATUS_N);
            list = projectMapper.getAuditScoreList(map);

        } else {
            map.put("izTop200", CommonConstant.COMMON_STATUS_Y);
            list = projectMapper.getAuditScoreList(map);
        }
        List<String> ids = new ArrayList<>();
        list.forEach(x -> {
            //当案例对应的是一线体育老师上传的案例时，先取视频数据，如果有视频，取视频快照，如果没有视频，则取对应的第一张图片，否则直接设置为空，前端显示默认图片
            if (CommonConstant.ROLE_TYPE_TE.equals(x.getRoleType())) {
                x.setSnapshotUrl(getSnapShotUrl(x.getProjectId()));
            }
            if (null != x.getRepetitionRate() || "".equals(x.getRepetitionRate())){
                BigDecimal repetitionRate = new BigDecimal(x.getRepetitionRate());
                BigDecimal hundred = new BigDecimal("100");
                x.setRepetitionRate(repetitionRate.multiply(hundred).toString());
            }
            x.setName(SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(x.getName()), SensitiveEnum.CHINESE_NAME));
            ids.add(x.getProjectId());
        });
        list = packageAuditScoreList(list, ids, CommonConstant.REVIEW_TYPE_ORDINARY);
        int selectedTotal = getFirstAuditScoreTotal(reqVO, CommonConstant.COMMON_STATUS_Y);
        int total = getFirstAuditScoreTotal(reqVO, CommonConstant.COMMON_STATUS_N);
        auditScoreListRespVO.setPageNo(reqVO.getPageNo());
        auditScoreListRespVO.setPageSize(reqVO.getPageSize());
        auditScoreListRespVO.setList(list);
        auditScoreListRespVO.setTotal(total);
        auditScoreListRespVO.setSelectedTotal(selectedTotal);
        return Result.OK("success", auditScoreListRespVO);
    }

    @Override
    public Result<AuditScoreListRespVO> getWinList(AuditScoreListReqVO reqVO) {
        List<AuditScoreVO> list;
        AuditScoreListRespVO auditScoreListRespVO = new AuditScoreListRespVO();
        Map<String, Object> map = new HashMap<>();
        int offset = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
        map.put("offset", offset);
        map.put("limit", reqVO.getPageSize());
        map.put("projectName", reqVO.getProjectName());
        map.put("caseType", reqVO.getCaseType());
        map.put("roleType", reqVO.getRoleType());
        Integer year;
        if (null != reqVO.getYear() && !"".equals(reqVO.getYear())) {
            year = Integer.valueOf(reqVO.getYear());
        } else {
            Calendar calendar = Calendar.getInstance();
            year = calendar.get(Calendar.YEAR);
            reqVO.setYear(year);
        }
        map.put("year", year);
        if (CommonConstant.DISPUTE_FIRST.equals(reqVO.getStatus())) {
            map.put("izWin", CommonConstant.COMMON_STATUS_N);
            list = projectMapper.getWinList(map);
        } else {
            map.put("izWin", CommonConstant.COMMON_STATUS_Y);
            list = projectMapper.getWinList(map);
        }
        List<String> ids = new ArrayList<>();
        list.forEach(x -> {
            //当案例对应的是一线体育老师上传的案例时，先取视频数据，如果有视频，取视频快照，如果没有视频，则取对应的第一张图片，否则直接设置为空，前端显示默认图片
            if (CommonConstant.ROLE_TYPE_TE.equals(x.getRoleType())) {
                x.setSnapshotUrl(getSnapShotUrl(x.getProjectId()));
            }
            x.setName(SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(x.getName()), SensitiveEnum.CHINESE_NAME));
            ids.add(x.getProjectId());
        });
        list = packageAuditScoreList(list, ids, CommonConstant.REVIEW_TYPE_SENIOR);
        int selectedTotal = getWinTotal(reqVO, CommonConstant.COMMON_STATUS_Y);
        int total = getWinTotal(reqVO, CommonConstant.COMMON_STATUS_N);
        auditScoreListRespVO.setPageNo(reqVO.getPageNo());
        auditScoreListRespVO.setPageSize(reqVO.getPageSize());
        auditScoreListRespVO.setList(list);
        auditScoreListRespVO.setTotal(total);
        auditScoreListRespVO.setSelectedTotal(selectedTotal);
        return Result.OK("success", auditScoreListRespVO);
    }

    public int getWinTotal(AuditScoreListReqVO reqVO, String izWin) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getIzWin, izWin);
        lambdaQueryWrapper.eq(SportsProject::getYear, reqVO.getYear());
        lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_SENIOR);
        if (null != reqVO.getCaseType() && !"".equals(reqVO.getCaseType())) {
            lambdaQueryWrapper.eq(SportsProject::getCaseType, reqVO.getCaseType());
        }
        if (null != reqVO.getRoleType() && !"".equals(reqVO.getRoleType())) {
            lambdaQueryWrapper.eq(SportsProject::getRoleType, reqVO.getRoleType());
        }
        if (null != reqVO.getProjectName() && !"".equals(reqVO.getProjectName())) {
            lambdaQueryWrapper.like(SportsProject::getProjectName, reqVO.getProjectName());
        }
        return projectMapper.selectList(lambdaQueryWrapper).size();
    }

    public int getFirstAuditScoreTotal(AuditScoreListReqVO reqVO, String status) {
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_ORDINARY);
        lambdaQueryWrapper.eq(SportsProject::getIzTop200, status);
        lambdaQueryWrapper.eq(SportsProject::getYear, reqVO.getYear());
        if (null != reqVO.getCaseType() && !"".equals(reqVO.getCaseType())) {
            lambdaQueryWrapper.eq(SportsProject::getCaseType, reqVO.getCaseType());
        }
        if (null != reqVO.getRoleType() && !"".equals(reqVO.getRoleType())) {
            lambdaQueryWrapper.eq(SportsProject::getRoleType, reqVO.getRoleType());
        }
        if (null != reqVO.getProjectName() && !"".equals(reqVO.getProjectName())) {
            lambdaQueryWrapper.like(SportsProject::getProjectName, reqVO.getProjectName());
        }
        List<SportsProject> list = projectMapper.selectList(lambdaQueryWrapper);
        return list.size();
    }

    public Integer getDisputeFirstTotal(String projectName, Integer year, String izTop200) {
        Integer total = 0;
        LambdaQueryWrapper<SportsProject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProject::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsProject::getYear, year);
        lambdaQueryWrapper.eq(SportsProject::getIzDispute, CommonConstant.COMMON_STATUS_Y);
        if (null == izTop200) {
            lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_ORDINARY);
            lambdaQueryWrapper.isNull(SportsProject::getFirstDisputeScore);
        } else {
            lambdaQueryWrapper.eq(SportsProject::getProjectStatus, CommonConstant.PROJECT_STATUS_FINISH_SENIOR);
            lambdaQueryWrapper.eq(SportsProject::getIzTop200, CommonConstant.COMMON_STATUS_Y);
            lambdaQueryWrapper.isNull(SportsProject::getFinalDisputeScore);
        }
        if (null != projectName && !"".equals(projectName)) {
            lambdaQueryWrapper.like(SportsProject::getProjectName, projectName);
        }
        List<SportsProject> list = projectMapper.selectList(lambdaQueryWrapper);
        if (null != list && list.size() > 0) {
            total = list.size();
            return total;
        }
        return total;
    }

    /**
     * 查询案例ID对应的资质文件
     *
     * @param projectId
     * @return
     */
    public SportsQualificationDoc getQualificationDocByProjectId(String projectId) {
        LambdaQueryWrapper<SportsQualificationDoc> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsQualificationDoc::getProjectId, projectId);
        queryWrapper.eq(SportsQualificationDoc::getIzActive, "0");
        return qualificationDocMapper.selectOne(queryWrapper);
    }

    /**
     * 查询案例ID对应的案例申报书信息
     *
     * @param projectId
     * @return
     */
    public SportsCaseReport getCaseReportByProjectId(String projectId) {
        LambdaQueryWrapper<SportsCaseReport> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsCaseReport::getProjectId, projectId);
        queryWrapper.eq(SportsCaseReport::getIzActive, CommonConstant.COMMON_STATUS_N);
        return caseReportMapper.selectOne(queryWrapper);
    }

    /**
     * 查询案例ID对应的案例学校工作情况信息
     *
     * @param projectId
     * @return
     */
    public SportsWorkInfo getWorkInfoByProjectId(String projectId) {
        LambdaQueryWrapper<SportsWorkInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsWorkInfo::getProjectId, projectId);
        queryWrapper.eq(SportsWorkInfo::getIzActive, CommonConstant.COMMON_STATUS_N);
        return workInfoMapper.selectOne(queryWrapper);
    }

    /**
     * 查询案例ID对应的案例个人信息
     *
     * @param projectId
     * @return
     */
    public PersonalInfoVO getPersonalInfo(String projectId, String roleType) {
        PersonalInfoVO personalInfoVO = new PersonalInfoVO();
        SportsPersonalInfo personalInfo = personalInfoMapper.selectByProjectId(projectId);
        String name = personalInfo.getName();
        String idNumber = personalInfo.getIdNumber();
        String email = personalInfo.getEmail();
        String phone = personalInfo.getPhone();
        String address = personalInfo.getAddress();

        SportsProject sportsProject = getSportsProjectById(projectId);
        name = SensitiveInfoUtil.getDecodeData(name);
        idNumber = SensitiveInfoUtil.getDecodeData(idNumber);
        email = SensitiveInfoUtil.getDecodeData(email);
        phone = SensitiveInfoUtil.getDecodeData(phone);
        address = SensitiveInfoUtil.getDecodeData(address);
       /* if (!CommonConstant.PROJECT_STEP_FINISH.equals(sportsProject.getProjectStep())) {
//        if (null == roleType) {
            //解密
            name = SensitiveInfoUtil.getDecodeData(name);
            idNumber = SensitiveInfoUtil.getDecodeData(idNumber);
            email = SensitiveInfoUtil.getDecodeData(email);
            phone = SensitiveInfoUtil.getDecodeData(phone);
            address = SensitiveInfoUtil.getDecodeData(address);
        } else {
            //解密 只显示一个姓，其余用*号代替
            name = SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(name), SensitiveEnum.CHINESE_NAME);
            idNumber = SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(idNumber), SensitiveEnum.ID_CARD);
            email = SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(email), SensitiveEnum.EMAIL);
            phone = SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(phone), SensitiveEnum.MOBILE_PHONE);
            address = SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(address), SensitiveEnum.ADDRESS);
        }*/
        personalInfo.setName(name);
        personalInfo.setIdNumber(idNumber);
        personalInfo.setEmail(email);
        personalInfo.setPhone(phone);
        personalInfo.setAddress(address);
        personalInfoVO.setPersonalInfo(personalInfo);

        LambdaQueryWrapper<SportsPersonalEdu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsPersonalEdu::getProjectId, projectId);
        queryWrapper.eq(SportsPersonalEdu::getIzActive, CommonConstant.COMMON_STATUS_N);
        List<SportsPersonalEdu> personalEdus = personalEduMapper.selectList(queryWrapper);
        if (null != personalEdus && personalEdus.size() > 0) {
            personalInfoVO.setPersonalEduList(personalEdus);
        }

        LambdaQueryWrapper<SportsPersonalWorkExperience> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(SportsPersonalWorkExperience::getProjectId, projectId);
        queryWrapper1.eq(SportsPersonalWorkExperience::getIzActive, CommonConstant.COMMON_STATUS_N);
        List<SportsPersonalWorkExperience> workExperiences = personalWorkExperienceMapper.selectList(queryWrapper1);
        personalInfoVO.setPersonalWorkExperienceList(workExperiences);
        //查询案例-个人信息-职称证书
        List<OssFileVO> professionalOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_PROFESSIONAL);
        if (null != professionalOssIds && professionalOssIds.size() > 0) {
            personalInfoVO.setProfessionalOssIds(professionalOssIds);
        } else {
            personalInfoVO.setProfessionalOssIds(professionalOssIds);
        }
        //查询案例-个人信息-荣誉证书
        List<OssFileVO> honorOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_HONOR);
        if (null != honorOssIds && honorOssIds.size() > 0) {
            personalInfoVO.setHonorOssIds(honorOssIds);
        }
        //查询案例-个人信息-代表性成果
        List<OssFileVO> resultOssIds = sportsProjectFileMapper.getOssUrl(projectId, CommonConstant.OSS_FILE_TYPE_RESULT);
        if (null != resultOssIds && resultOssIds.size() > 0) {
            personalInfoVO.setResultCoverOssIds(resultOssIds);
        }
        return personalInfoVO;
    }
}
